package commands;

import util.Util;
import core.Card;
import core.Location;
import core.Zone;

/**
 * Represents a command to move a Card from one Zone to another.
 */
public class MoveCardCommand extends CardCommand
{
	/**
	 * Default constructor for reflection purposes.
	 */
	public MoveCardCommand() {
		this(null, null, null);
	}
	
	/**
	 * Creates a new generic MoveCommand that moves the card to the default location
	 * in the destination zone
	 * @param card the card to move
	 * @param fromZone the zone to move the card from
	 * @param toZone the zone to move the card to
	 */
	public MoveCardCommand(Card card, Zone zone) {
		this(card, zone, null);
	}

	/**
	 * Creates a new generic MoveCommand that moves the card to a specified location
	 * in the destination zone
	 * @param card the card to move
	 * @param fromZone the zone to move the card from
	 * @param toZone the zone to move the card to
	 * @param loc the location for the card to assume in its destination zone
	 */
	public MoveCardCommand(Card card, Zone zone, Location loc)
	{
		setCard(card);
		setZone(zone);
		setLocation(loc);
	}

	// TODO: make this pay attention to locations again
	public net.StateUpdate execute() throws CommandException
	{
		if (zone == null || card == null)
			throw new CommandException(this, "Bad parameter in move command");
		net.StateUpdate stateUpdate = super.execute();
		stateUpdate.addChange(new net.ChildRemoval(oldZone, "card", card));
		Card newCard = new Card(card);
		if (location != null)
			newCard.setLocation(location);
		else
			newCard.setLocation(zone.getDefaultLocation());
		if (zone != oldZone)
			newCard.setVisibility(zone.getDefaultVisibility());
		stateUpdate.addChange(new net.ChildAddition(zone, "card", newCard));
		return stateUpdate;
	}

	public String toString() {
		return card + " from " + oldZone + " to " + zone + (location == null ? "" : " at " + location);
	}

	public void setCard(Card card) {
		super.setCard(card);
		this.oldZone = (card == null ? null : card.getZone());
	}

	public Zone getZone() {
		return zone;
	}

	public void setZone(Zone zone) {
		this.zone = zone;
	}

	public Location getLocation() {
		return location;
	}

	public void setLocation(Location location) {
		this.location = location;
	}

	public String getMessage() {
		return "move " + Util.prettyPrint(card) + " from " + Util.prettyPrint(oldZone) + " to " + Util.prettyPrint(zone) + (location != null ? " at " + location : "");
	}

	private Zone zone, oldZone = null;
	private Location location;
}